﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Configuration;
using JQuery.WebKit.WebCommon;
using Newtonsoft.Json.Linq;

namespace JQuery.WebKit.Util
{
    public class JUtil
    {
        public static object JConvert(JToken value)
        {
            if (value == null)
            {
                return null;
            }
            List<object> jsonList = null;
            List<object> retList = null;
            switch (value.Type)
            {
                case JTokenType.Array:
                    jsonList = value.Values().ToList<object>();
                    retList = new List<object>();
                    jsonList.ForEach(item => retList.Add((item as JValue).Value));
                    return retList;
                case JTokenType.Boolean:
                    return value.Value<bool>();
                case JTokenType.Bytes:
                    return value.Value<byte>();
                case JTokenType.Comment:
                    return value.Value<string>();
                case JTokenType.Constructor:
                    return value.Value<string>();
                case JTokenType.Date:
                    return value.Value<DateTime>();
                case JTokenType.Float:
                    return value.Value<float>();
                case JTokenType.Integer:
                    return value.Value<int>();
                case JTokenType.None:
                    return null;
                case JTokenType.Null:
                    return null;
                case JTokenType.Object:
                    object[] objList = value.ToArray();

                    Dictionary<object, object> dictRet = new Dictionary<object, object>();
                    foreach (JProperty prop in objList)
                    {
                        dictRet.Add(prop.Name, JUtil.JConvert(prop.Value));
                    }
                    return dictRet;
                case JTokenType.Property:
                    return value.Value<string>();
                case JTokenType.Raw:
                    return value.Value<string>();
                case JTokenType.String:
                    return value.Value<string>();
                case JTokenType.Undefined:
                    return null;
                default:
                    return null;
            }
        }

        public static Hashtable GetRequestJSONCollection()
        {
            Hashtable JSONCollection = new Hashtable();

            HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
            System.IO.TextReader sr = new System.IO.StreamReader(HttpContext.Current.Request.InputStream);
            string line = sr.ReadToEnd();

            if (!string.IsNullOrEmpty(line))
            {
                JObject obj = JObject.Parse(line);
                List<object> objList = obj.ToList<object>();

                foreach (JProperty prop in objList)
                {
                    JSONCollection.Add(prop.Name, JUtil.JConvert(prop.Value));
                }
            }
            return JSONCollection;
        }

        public static string GetBasePath()
        {
            string path = string.Format("{0}://{1}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority);
            int segmentsCount = HttpContext.Current.Request.Url.Segments.Length;
            if (HttpContext.Current.Request.Url.Segments.Length >= 1)
            {
                for (int i = 0; i < segmentsCount; i++)
                {
                    path += HttpContext.Current.Request.Url.Segments[i];
                    if (path.EndsWith(".aspx") ||
                        path.EndsWith(".aspx/") ||
                        path.EndsWith(".asmx") ||
                        path.EndsWith(".asmx/"))
                    {
                        break;
                    }
                }
            }
            NameValueCollection qs = GetPageQueryString();// WebUtil.ParseUrlParameters(HttpContext.Current.Request.Url.Query);
            //List<string> queryStr = new List<string>();
            //foreach (string key in qs.Keys)
            //{
            //    if (qs[key].EndsWith("/Refresh"))
            //    {
            //        queryStr.Add(string.Format("{0}={1}", key, qs[key].Substring(0, qs[key].Length - 9)));
            //    }
            //    else if (qs[key].EndsWith("/SetPostBackData"))
            //    {
            //        queryStr.Add(string.Format("{0}={1}", key, qs[key].Substring(0, qs[key].Length - 16)));
            //    }
            //    else
            //    {
            //        queryStr.Add(string.Format("{0}={1}", key, qs[key]));
            //    }
            //}
            if (qs.Count > 0)
            {
                return string.Format("{0}?{1}", path.EndsWith("/") ? path.Substring(0, path.Length - 1) : path, string.Join("&", qs.AllKeys.Select(key => string.Format("{0}={1}", key, qs[key]))));
            }
            return path.EndsWith("/") ? path.Substring(0, path.Length - 1) : path;
        }

        public static Uri GetPageUri()
        {
            return new Uri(GetBasePath());
        }

        public static NameValueCollection GetPageQueryString()
        {
            NameValueCollection qs = WebUtil.ParseUrlParameters(HttpContext.Current.Request.Url.Query);
            //for (int i = 0; i < qs.Count; i++)
            //{
            //    if (qs[i].EndsWith("/Refresh"))
            //    {
            //        qs[qs.Keys[i]] = qs[i].Substring(0, qs[i].Length - 9);
            //    }
            //    else if (qs[i].EndsWith("/SetPostBackData"))
            //    {
            //        qs[qs.Keys[i]] = qs[i].Substring(0, qs[i].Length - 16);
            //    }
            //}
            return qs;
        }

        //internal static ISecurityPrincipal Authenticate(JPage page)
        //{
        //    JSecurityPrincipal principal = (JSecurityPrincipal)HttpContext.Current.Session["ISecurityPrincipal"];
        //    if (principal == null)
        //    {
        //        principal = new JSecurityPrincipal(new JIdentityPrincipal(null, string.Empty, principal), page);
        //        HttpContext.Current.Session["ISecurityPrincipal"] = principal;
        //    }
        //    return principal;
        //}

        public static int GetMaxRequestLength()
        {
            System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
            object o = config.GetSection("system.web/httpRuntime");
            HttpRuntimeSection section = o as HttpRuntimeSection;
            return section.MaxRequestLength;
        }

        public class Imaging
        {
            #region public static Image FromByteArray(object byteArray)
            /// <summary>
            /// 
            /// </summary>
            /// <param name="byteArray"></param>
            /// <returns></returns>
            public static Image FromByteArray(object byteArray)
            {
                if (byteArray == null || byteArray.Equals(DBNull.Value))
                {
                    return null;
                }
                try
                {

                    if (byteArray is Image)
                    {
                        return byteArray as Image;
                    }

                    if (!(byteArray is byte[]))
                    {
                        return null;
                    }
                    if (((byte[])byteArray).Length == 0)
                        return null;

                    MemoryStream ms = new MemoryStream(byteArray as byte[]);
                    Bitmap bmp = (Bitmap)Bitmap.FromStream(ms, true, true);

                    //ensure a 32bpp non indexed pixel format (bypass graphics draw bug)
                    switch (bmp.PixelFormat)
                    {
                        case PixelFormat.Undefined:
                        case PixelFormat.Format1bppIndexed:
                        case PixelFormat.Format4bppIndexed:
                        case PixelFormat.Format8bppIndexed:
                        case PixelFormat.Format16bppGrayScale:
                        case PixelFormat.Format16bppArgb1555:
                            bmp = new Bitmap(bmp);
                            break;
                    }
                    return bmp;
                }
                catch
                {
                    return null;
                }

            }
            #endregion

            #region public static byte[] ToByteArray(object image)
            /// <summary>
            /// 
            /// </summary>
            /// <param name="image"></param>
            /// <returns></returns>
            public static byte[] ToByteArray(object image)
            {
                if (image == null || image.Equals(DBNull.Value))
                {
                    return null;
                }
                using (MemoryStream ms = new MemoryStream())
                {
                    (image as Image).Save(ms, ImageFormat.Jpeg);
                    return ms.ToArray();
                }
            }
            #endregion
        }
    }
}
